/*
 * Flashlib - QB9 common Flash library
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */


package com.qb9.flashlib.display
{
	import com.qb9.flashlib.interfaces.IDisposable;
	import com.qb9.flashlib.interfaces.IMoveable;
	import com.qb9.flashlib.utils.DisplayUtil;
	
	import flash.display.*;
	
	/**
	 * Enhanced Sprite class.
	 *
	 * <p>This class adds shortcut methods for using named DisplayObjects as layers.  Usage example:
	 * <pre>
	 * 	public class MySprite extends QSprite
	 * 	{
	 * 		public function MySprite()
	 * 		{
	 * 			// Define layer tree (each call creates a new QSprite instance):
	 * 			addLayer('background');
	 * 			addLayer('background.sublayer1');
	 * 			addLayer('background.sublayer2');
	 * 			addLayer('foreground');
	 * 			
	 * 			// Add a movieclip to the foreground layer:
	 * 			addChildAtPath('foreground', new MovieClip());
	 * 			
	 * 			// Add a movieclip named 'foo' to the background layer:
	 * 			addNamedChildAtPath('background.sublayer1', 'foo', new MovieClip());
	 * 			
	 * 			// Access 'foo':
	 * 			assert(getChildByPath('background.sublayer1.foo') is MovieClip);
	 * 		}
	 * 	}
	 * </pre>
	 * </p>
	 */
	public class QSprite extends Sprite implements IDisposable, IMoveable
	{
		public function QSprite()
		{
		}

		/**
		 * Add a DisplayObject at the given path.
		 *
		 * @param path Sequence of names delimited by '.'.  Example: 'background.foo.bar' (in this case, the DisplayObject will be added to the DisplayObjectContainer named 'bar').
		 * @param child DisplayObject to be added.
		 */
		public function addChildAtPath(path:String, child:DisplayObject):void
		{
			(getChildByPath(path) as DisplayObjectContainer).addChild(child);
		}
		
		/**
		 * Add a DisplayObject at the given path, and give it a name.
		 *
		 * <p>After this call, the child DisplayObject can be accessed with <code>getChildByPath('[path].[name]')</code></p>
		 *
		 * @param path Sequence of names delimited by '.'.  Example: 'background.foo.bar' (in this case, the DisplayObject will be added to the DisplayObjectContainer named 'bar').
		 * @param name The name to be given to the child DisplayObject.
		 * @param child DisplayObject to be added.
		 *
		 * @see addChildAtPath
		 */
		public function addNamedChildAtPath(path:String, name:String, child:DisplayObject):void
		{
			child.name = name;
			addChildAtPath(path, child);
		}
		
		/**
		 * Add a DisplayObject, and give it a name. Equivalent to <code>addNamedChildAtPath('', name, child)</code>
		 *
		 * <p>After this call, the child DisplayObject can be accessed with either <code>getChildByName('[name]')</code> or <code>getChildByPath('[name]')</code></p>
		 *
		 * @param name The name to be given to the child DisplayObject.
		 * @param child DisplayObject to be added.
		 */
		public function addNamedChild(name:String, child:DisplayObject):void
		{
			addNamedChildAtPath('', name, child);
		}
		
		/**
		 * Find a DisplayObject given its path.
		 *
		 * @param path Sequence of names delimited by '.'.  Example: 'background.foo.bar' (in this case, the returned DisplayObject will be the one named 'bar').
		 */
		public function getChildByPath(path:String):DisplayObject
		{
			return DisplayUtil.getByPath(this, path);
		}

		/**
		 * Add a new layer, which is an empty QSprite with a given name.
		 *
		 * @param path Sequence of names delimited by '.'.  Example: 'background.foo.bar' (in this case, 'background' and 'foo' must exist already, and the new QSprite will be named 'bar').
		 */
		public function addLayer(path:String):QSprite
		{
			var child:QSprite = new QSprite;
			var names:Array = path.split('.');
			var name:String = names.pop();
			addNamedChildAtPath(names.join('.'), name, child);
			return child;
		}

		/** Remove the QSprite from the display list. */
		public function dispose():void
		{
			DisplayUtil.dispose(this);
		}
	}
}

